using System;
using System.ComponentModel;
using System.Web.UI;

namespace Altairis.Web.UI.WebControls {

    /// <summary>
    /// Control for displaying date and time values.
    /// Different format string values can be specified for general date, today, yesterday and tomorrow.
    /// So you can have date formatted generally as "dd. MM. yyyy", or "today HH:mm".
    /// </summary>
    [DefaultProperty("Text")]
    public class DateLabel : System.Web.UI.WebControls.Label {

        /// <summary>
        /// Initializes a new instance of the <see cref="DateLabel"/> class.
        /// </summary>
        public DateLabel() {
            this.TodayText = Properties.Resources.DateFormatStringToday;
            this.YesterdayText = Properties.Resources.DateFormatStringYesterday;
            this.TomorrowText = Properties.Resources.DateFormatStringTomorrow;
            this.Text = Properties.Resources.DateFormatStringGeneral;
            this.NullDateValue = DateTime.MinValue;
            this.NullText = Properties.Resources.DateFormatStringNull;
        }

        /// <summary>
        /// Gets or sets date value to be displayed in label.
        /// </summary>
        [Bindable(true), Category("Behavior")]
        [Description("Gets or sets date value to be displayed in label.")]
        public string DateValue {
            get { return (string)this.ViewState["DateValue"]; }
            set { this.ViewState["DateValue"] = value; }
        }

        /// <summary>
        /// Gets or sets date value to be considered as null date. By default, DateTime.MinValue.
        /// </summary>
        [Category("Behavior")]
        [Description("Gets or sets date value to be considered as null date. By default, DateTime.MinValue.")]
        public DateTime NullDateValue {
            get { return (DateTime)(this.ViewState["NullDateValue"] ?? DateTime.MinValue); }
            set { this.ViewState["NullDateValue"] = value; }
        }

        /// <summary>
        /// Gets or sets text for null date.
        /// </summary>
        [Localizable(true), Bindable(true), Category("Appearance"), Themeable(true)]
        [Description("Gets or sets text for null date.")]
        public string NullText {
            get { return (string)this.ViewState["NullText"]; }
            set { this.ViewState["NullText"] = value; }
        }

        /// <summary>
        /// Gets or sets format string for general date.
        /// </summary>
        [Localizable(true), Bindable(true), Category("Appearance"), Themeable(true)]
        [Description("Gets or sets format string for general date.")]
        new public string Text {
            get { return (string)this.ViewState["Text"]; }
            set { this.ViewState["Text"] = value; }
        }

        /// <summary>
        /// Gets or sets format string for 'today' date.
        /// </summary>
        [Localizable(true), Bindable(true), Category("Appearance"), Themeable(true)]
        [Description("Gets or sets format string for 'today' date.")]
        public string TodayText {
            get { return (string)this.ViewState["TodayText"]; }
            set { this.ViewState["TodayText"] = value; }
        }

        /// <summary>
        /// Gets or sets format string for 'tomorrow' date.
        /// </summary>
        [Localizable(true), Bindable(true), Category("Appearance"), Themeable(true)]
        [Description("Gets or sets format string for 'tomorrow' date.")]
        public string TomorrowText {
            get { return (string)this.ViewState["TomorrowText"]; }
            set { this.ViewState["TomorrowText"] = value; }
        }

        /// <summary>
        /// Gets or sets format string for 'yesterday' date.
        /// </summary>
        [Localizable(true), Bindable(true), Category("Appearance"), Themeable(true)]
        [Description("Gets or sets format string for 'yesterday' date.")]
        public string YesterdayText {
            get { return (string)this.ViewState["YesterdayText"]; }
            set { this.ViewState["YesterdayText"] = value; }
        }

        protected override void Render(HtmlTextWriter writer) {
            string s = this.Text;
            this.Text = this.GetText();
            base.Render(writer);
            this.Text = s;
        }

        private string GetText() {
            DateTime date;
            var r = DateTime.TryParse(this.DateValue, out date);
            if (!r || date == this.NullDateValue) {
                // Null or invalid
                return this.NullText;
            }
            else if (date.Date == DateTime.Today) {
                // Today
                return string.Format(this.TodayText, date);
            }
            else if (date.Date == DateTime.Today.AddDays(-1)) {
                // Yesterday
                return string.Format(this.YesterdayText, date);
            }
            else if (date.Date == DateTime.Today.AddDays(1)) {
                // Tomorrow
                return string.Format(this.TomorrowText, date);
            }
            else {
                // Generic
                return string.Format(this.Text, date);
            }
        }
    }
}